<template>
  <div class="map">
    <canvas id="canvasPath" width="1920" height="750"></canvas>
  </div>
</template>

<script>
  export default {
    name: '',
    data() {
      return {
        mapCoordinateList: [ { x: 10, y: 10 }, { x: 20, y: 10 }, { x: 300, y: 10, }, { x: 650, y: 10, }, { x: 650, y: 300 }, { x: 300, y: 500 },  { x: 10, y: 500 }], // 小车实时位置list
        mapIndex: 0, // 实时点位list下标
        afterLaugl: 0,
        moveLen: 0,
      }
    },

    created() {
    },

    mounted() {
      // 创建轨迹画布
      this.createCanvasPath()
      // 创建AGV画布
      this.createCanvasAgv()
    },

    methods: {
      // 轨迹绘画方法
      createCanvasPath() {
        // 初始化canvas
        const myContext = document.getElementById('canvasPath')
        const canvas = myContext.getContext('2d')
        // 启动路径
        canvas.beginPath()
        // 绘制移动点位
        this.mapCoordinateList.forEach((item, index) => {
          if(index+1 < this.mapCoordinateList.length) {
            // 绘制的起点
            canvas.moveTo(item.x, item.y)
            // 绘制的终点
            canvas.lineTo(this.mapCoordinateList[index+1].x, this.mapCoordinateList[index+1].y)
          } else {
            canvas.moveTo(item.x, item.y)
            canvas.lineTo(this.mapCoordinateList[0].x, this.mapCoordinateList[0].y)
          }
        })
        // 绘制已经定义的路径
        canvas.stroke()
      },

      // 创建小车行驶画布
      createCanvasAgv() {
        this.moveLen = this.mapCoordinateList.length
        const map = document.querySelector(".map")
        // 创建canvas
        const myCanvas = document.createElement('canvas')
        myCanvas.className = 'canvas'
        myCanvas.width = 1920
        myCanvas.height = 750
        myCanvas.style.position = 'absolute'
        myCanvas.style.left = 0
        myCanvas.style.top = 0
        myCanvas.style.backgroundColor = 'rgba(0,0,0,0)'
        myCanvas.style.Zindex = 2
        map.appendChild(myCanvas)
        const canvas = myCanvas.getContext('2d')
        // 启动路径
        canvas.beginPath()
        this.handleMove(canvas, map, myCanvas)
      },

      // AGV移动原点判断
      handleMove(canvas) {
        if(this.mapIndex) {
          // 非第一个点位
          const valx = this.mapCoordinateList[this.mapIndex].x - this.mapCoordinateList[this.mapIndex-1].x
          const valy = this.mapCoordinateList[this.mapIndex].y - this.mapCoordinateList[this.mapIndex-1].y
          // 计算移动轨迹长度
          const len = Math.sqrt(valx*valx+valy*valy)
          // 往x轴方向平移坐标原点
          canvas.translate(len, 0)
        } else {
          // 是第一个点位，将原点平移到第一个移动点位上，重新映射原点
          canvas.translate(this.mapCoordinateList[this.mapIndex].x, this.mapCoordinateList[this.mapIndex].y)
        }
        const valx = this.mapCoordinateList[this.mapIndex+1].x - this.mapCoordinateList[this.mapIndex].x
        const valy = this.mapCoordinateList[this.mapIndex+1].y - this.mapCoordinateList[this.mapIndex].y

        // 计算当前坐标与x轴正方向的角度
        let laugl = this.handleGetGugle(valx, valy)
        // 定义移动距离
        let moveIndex = 0
        // 计算两个坐标点之间的距离
        const len = Math.sqrt(valx*valx+valy*valy)
        // 计算需要移动的角度，角度被放大，每次动画执行0.01角度
        const lauglLen = Math.floor((laugl - this.afterLaugl) * 100)
        const surplus = laugl - this.afterLaugl - lauglLen / 100
        let index = 0
        // 旋转角度定时器
        const lauglTime = setInterval(() => {
          // 清空一个矩形
          canvas.clearRect(-11, -6, 1920, 750)
          // 判断移动的角度 > 0
          if(index < Math.abs(lauglLen)) {
            // 绘制小车
            canvas.strokeRect( - 10, -5, 20, 10)
            if(lauglLen > 0) {
              // 让小车旋转每10毫秒0.01角度
              canvas.rotate(0.01)
            } else {
              canvas.rotate(-0.01)
            }
            // 旋转角度值
            index++
          } else {
            // 若角度不足0.01小车移动时将自动旋转
            canvas.rotate(surplus)
            // 清除定时器
            clearInterval(lauglTime)
            const timer = setInterval(() => {
              canvas.clearRect(-11, -6, 1920, 750)
              canvas.strokeRect(moveIndex - 10, -5, 20, 10)
              canvas.stroke()
              if(moveIndex < len) {
                // 移动距离小于两点之间长度
                moveIndex += 1
              } else {
                // 清除移动定时器
                clearInterval(timer)
                // 判断当前点位是否超过移动点位数量
                if(this.mapIndex > this.moveLen ) {
                  // 超过再次循环
                  this.mapIndex = 1
                  this.mapCoordinateList.splice(0, this.moveLen)
                }
                if(this.mapIndex < this.mapCoordinateList.length - 2){
                  // 模拟自动移动
                  this.mapIndex++
                  // 获取角度跟长度，进行模拟运行
                  this.handleMove(canvas)
                } else {
                  this.mapCoordinateList.push(...this.mapCoordinateList)
                  this.mapIndex++
                  this.handleMove(canvas)
                }
              }
            }, 10)
            moveIndex++
          }
        }, 10)
        this.afterLaugl = laugl
      },

      // 计算坐标与x轴正方向的角度
      handleGetGugle(valx, valy) {
        // 定义反正切值
        let laugl = 0
        // 当x轴 > 0
        if(valx > 0) {
          // 当y轴 > 0
          if(valy >= 0 ) {
            // 获取反正切值（即b/a对角角度）
            laugl = Math.atan(valy / valx)
          } else {
            // y < 0（即(1.5Π+atan(|a/b|))要旋转的角度）
            laugl = Math.atan(Math.abs(valx / valy)) + 1.5*Math.PI
          }
        } else if(valx < 0) {
          // x < 0
          if(valy > 0) {
            // 当y轴 > 0（即(0.5Π+atan(|a/b|))
            laugl = Math.atan(Math.abs(valx / valy)) + 0.5*Math.PI
          } else if(valy < 0) {
            // 当y轴 < 0（即Π+atan(|b/a|)）
            laugl = Math.atan(valy / valx) + Math.PI
          } else {
            // 同Y轴，（x2-x1）< 0（即Π）
            laugl = Math.PI
          }
        } else {
          // 同X轴
          if (valy > 0) {
            // (y2-y1) > 0（即角度为Π/2）
            laugl = Math.PI*0.5
          } else {
            // (y2-y1) < 0（即角度为1.5Π）
            laugl = Math.PI*1.5
          }
        }
        return laugl
      }
    }
  }
</script>

<style lang="scss" scoped>
  .map{
    position: relative;
    .canvasPath{
      z-index: 1;
    }
  }
</style>
